#include <54func.h>
char setTypeMode(mode_t mode,char *str)//将传入的参数转换为字符类型！！！
{
    //文件权限获取
    switch (mode & S_IFMT) {
    case S_IFBLK:  str[0] = 'b';            
                   break;
    case S_IFCHR:  str[0] = 'c';       
                   break;
    case S_IFDIR:  str[0] = 'd';              
                   break;
    case S_IFIFO:  str[0] = 'p';  
    case S_IFLNK:  str[0] = 'l';                
                   break;
    case S_IFREG:  str[0] = '-';       
                   break;
    case S_IFSOCK: str[0] = 's';      
                   break;
    default:       str[0] = '?';  
                   break;
    }
    int i = 1<<8;//100000000 左移8位
    if(mode & i){//1 真 0 假
        str[1] = 'r';
    }else{
        str[1] = '-';
    }
    i >>= 1;//右移1位
    if(mode & i ){
        str[2] = 'w';
    }else{
        str[2] = '-';
    }
    i >>= 1;
    if(mode & i){
        str[3] = 'x';
    }else{
        str[3] = '-';
    }
    i >>= 1;
    if(mode & i){
        str[4] = 'r';
    }else{
        str[4] = '-';
    }
    i >>= 1;
    if(mode & i ){
        str[5] = 'w';
    }else{
        str[5] = '-';
    }
    i >>= 1;
    if(mode & i){
        str[6] = 'x';
    }else{
        str[6] = '-';
    }
    i >>= 1;
    if(mode & i){
        str[7] = 'r';
    }else{
        str[7] = '-';
    }
    i >>= 1;
    if(mode & i ){
        str[8] = 'w';
    }else{
        str[8] = '-';
    }
    i >>= 1;
    if(mode & i){
        str[9] = 'x';
    }else{
        str[9] = '-';
    }
    str[10] = '\0';
    return 0;
}
int main(int argc,char *argv[])
{
    //dirent:读取目录文件的内容,不仅仅是针对当前目录，因此需要命令行参数
    // ./10_myls_al.c dir1
    ARGS_CHECK(argc,2);
    DIR *dirp = opendir(argv[1]);

    ERROR_CHECK(dirp,NULL,"opendir");
    //读取（结构体）目录下的所有文件：循环+遍历（目录从磁盘到内存，会有一个位置指针，会自己自动滑动到下一个目录项）
    struct dirent * pdirent;//先定义一个指向结构体的指针,指向该结构体
    //犯了野指针错误！！
    //pdirent = readdir(dirp);//这是错误的写法，因为pdirent指针在循环中没有被更新，意味着始终指向同一个结构体，而不是流向到下一个目录项
    //循环+遍历    >> 读到目录流的末尾，则会返回NULL
    while((pdirent = readdir(dirp)) != NULL){
        //文件名 -> 路径 我们在这里是要查看dir1目录下的文件
        char path[1024] = {0};
        sprintf(path,"%s%s%s",argv[1],"/",pdirent->d_name);
        //有了路径，接下来将路径传入到stat函数，去获取更具体的信息
        
        //struct stat *pstat;//野指针问题！！！patat指向的内存没有申请
        struct stat statbuf;//在内存的栈上申请了结构体变量
        int ret = stat(path,&statbuf);
        ERROR_CHECK(ret,-1,"stat");
    
        //str保存类型和权限
        char str[20] = {0};
        setTypeMode(statbuf.st_mode,str);//stat中st_mode类型为mode_t
        
        struct passwd *pgetuid = getpwuid(statbuf.st_uid);//从uid获取姓名
        struct group *pgetgid = getgrgid(statbuf.st_gid);//从gid获取组名
        struct tm *ptm = localtime(&statbuf.st_mtime);

        //输出打印
        printf("%s %ld %s %s %4ld %d %d %02d:%02d %s\n",
                    //statbuf.st_mode,
                    str,
                    statbuf.st_nlink,
                    pgetgid->gr_name,
                    //statbuf.st_uid,
                    pgetuid->pw_name,
                    //pgetuidbuf.pw_name,
                    //statbuf.st_gid,
                    statbuf.st_size,
                    ptm->tm_mon,ptm->tm_mday,ptm->tm_hour,ptm->tm_min,
                    //statbuf.st_mtime,
                    pdirent->d_name);

    }
    closedir(dirp);

    return 0;
}
